package com.stardata.liangshisq.tcslmon.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.stardata.liangshisq.tcslmon.entity.*;
import com.stardata.liangshisq.tcslmon.service.*;
import com.stardata.liangshisq.tcslmon.util.NoTimeArchItemUtil;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@AllArgsConstructor
public class OrderExceptionTask {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final KcKscService kcKscService;
    private final BizBsService bizBsService;

    private final SysParameterService parameterService;

    private final BizBiOrderDayService bizBiOrderDayService;

    private final TbBizBsTimeService tbBizBsTimeService;

    private final TbKcKscTimeService tbKcKscTimeService;

    /**
     * 更新所有的菜品的时间
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void OrderExceptionGet() {
        LocalDateTime now = LocalDateTime.now();
        // 1. 查询 ksc 表中  kc_ksc_time 表中的数据 order_call_time =0 的数据
        QueryWrapper<TbKcKscTime> wrapper = new QueryWrapper<TbKcKscTime>();
        wrapper.between("call_up_time", now.with(LocalTime.MIN), now.with(LocalTime.MAX));
        wrapper.eq("order_call_time", 0);
        wrapper.last("limit 20");
        wrapper.orderBy(true, true, "modify_time");
        List<TbKcKscTime> tbKcKscTimeList = tbKcKscTimeService.list(wrapper);
        List<Long> kcKscIds = new ArrayList<>();
        Map<Long, TbKcKscTime> tbKcKscTimeHashMap = new HashMap<>();
        for (TbKcKscTime tbKcKscTime : tbKcKscTimeList) {
            kcKscIds.add(tbKcKscTime.getId());
            tbKcKscTimeHashMap.put(tbKcKscTime.getId(), tbKcKscTime);
        }
        // 2. 表kc_ksc 数据获取加工时间
        QueryWrapper<KcKsc> kcWrapper = new QueryWrapper<KcKsc>();
        if (kcKscIds.isEmpty()) {
            return;
        }
        kcWrapper.in("id", kcKscIds);
        List<KcKsc> kcKscList = kcKscService.list(kcWrapper);
        // 更新订单计时状态
        for (KcKsc item : kcKscList) {
            TbKcKscTime tbKcKscTime = tbKcKscTimeHashMap.get(item.getId());
            if (tbKcKscTime == null) {
                continue;
            }
            if (NoTimeArchItemUtil.noTimeArchItem().contains(item.getItemId())) {
                // 加入是 米饭 打包盒 啥的 ， 设置时间为1
                tbKcKscTime.setOrderCallTime(1L);
                tbKcKscTime.setModifyTime(LocalDateTime.now());
            } else if (item.getLastQty().doubleValue() < 0.001) {
                // 退单的 设置时间为-1
                tbKcKscTime.setOrderCallTime(-1L);
                tbKcKscTime.setModifyTime(LocalDateTime.now());
            } else if (item.getKitchenFlg() != 3) {
                // 正常订单 未完成加工的持续加工,修改更新时间
                tbKcKscTime.setOrderCallTime(0L);
                tbKcKscTime.setModifyTime(LocalDateTime.now());
            } else {
                // 正常订单已经完成加工了 则设置加工时长
                LocalDateTime callUpTime = item.getCallUpTime();
                LocalDateTime serveFinishTime = item.getServeFinishTime();
                // 得到菜品的开始时间和实际上菜时间的时间间隔，作为菜品的加工时长
                Long timeLim = Duration.between(callUpTime, serveFinishTime).getSeconds();
                logger.info("菜品的开始时间{}，菜品的完成时间{},时间间隔{}", callUpTime, serveFinishTime, timeLim);
                tbKcKscTime.setOrderCallTime(timeLim);
                tbKcKscTime.setModifyTime(LocalDateTime.now());
            }
            tbKcKscTimeService.saveOrUpdate(tbKcKscTime);
        }
    }

    // @Scheduled(cron = "* 0/1 * * * ?")
    @Scheduled(cron = "0/30 * * * * ?")
    private void orderKscDataSync() {
        QueryWrapper<TbBizBsTime> wrapper = new QueryWrapper<TbBizBsTime>();
        LocalDateTime now = LocalDateTime.now();
        wrapper.between("open_time", now.with(LocalTime.MIN), now.with(LocalTime.MAX));
        wrapper.orderBy(true, true, "modify_time");
        wrapper.last("limit 20");
        //查询结算时间不为空，且同步状态不等于2的订单信息
        List<TbBizBsTime> orderList = tbBizBsTimeService.list(wrapper);
        //获取所有的菜品信息， 更新菜品的分类
        for (TbBizBsTime item : orderList) {
            // 1。 获取该 订单的 时间信息
            QueryWrapper<TbKcKscTime> tbKcKscTimeQueryWrapper = new QueryWrapper<TbKcKscTime>();
            tbKcKscTimeQueryWrapper.eq("bs_id", item.getId());
            List<TbKcKscTime> tbKcKscTimeList = tbKcKscTimeService.list(tbKcKscTimeQueryWrapper);
            Map<Long, TbKcKscTime> tbKcKscTimeHashMap = new HashMap<>();
            for (TbKcKscTime tbKcKscTime : tbKcKscTimeList) {
                tbKcKscTimeHashMap.put(tbKcKscTime.getId(), tbKcKscTime);
            }
            QueryWrapper<KcKsc> kcKscQueryWrapper = new QueryWrapper<KcKsc>();
            kcKscQueryWrapper.eq("bs_id", item.getId());
            List<KcKsc> kcKscList = kcKscService.list(kcKscQueryWrapper);
            Long timeLim = 0L;
            Integer bsKcCount = 0; //  菜品数量
            for (KcKsc kcKsc : kcKscList) {
                TbKcKscTime tbKcKscTime = tbKcKscTimeHashMap.get(kcKsc.getId());
                if (tbKcKscTime == null) {
                    continue;
                }
                if (kcKsc.getLastQty().doubleValue() < 0.001) { // 退单的 不需要核算
                    continue;
                }
                if (kcKsc.getKitchenFlg() != 3) { // 没有完成的 不需要核算
                    continue;
                }
                Long orderCallTime = tbKcKscTime.getOrderCallTime();
                if (orderCallTime.compareTo(timeLim) > 0) {
                    timeLim = orderCallTime;
                }
                bsKcCount++;
            }
            item.setBsKcCount(bsKcCount);
            item.setOrderCallTime(timeLim);
            item.setModifyTime(LocalDateTime.now());
            tbBizBsTimeService.updateById(item);
        }
    }

    /**
     * 1. 超时多少订单，超时多少菜，
     * 2. 今日菜品平均耗时：8分钟，历史最优：5分钟；【当日所有的菜品总耗时/菜品数】
     * 3. 总多少订单，总多少菜
     */

    @Scheduled(cron = "* 0/1 * * * ?")
    private void orderKscDatabi() {
        String shopId = parameterService.getByCode("shopId");
        LocalDate settleBizDate = LocalDate.now();
        QueryWrapper<BizBiOrderDay> wrapper = new QueryWrapper<>();
        wrapper.eq("shop_id", Long.valueOf(shopId)).eq("settle_biz_date", LocalDate.now());
        BizBiOrderDay bizBiOrderDay = bizBiOrderDayService.getOne(wrapper, true);
        if (bizBiOrderDay == null) {
            bizBiOrderDay = new BizBiOrderDay();
            bizBiOrderDay.setShopId(Long.valueOf(shopId));
            bizBiOrderDay.setSettleBizDate(settleBizDate);
        }

        // 计算 总多少订单，超时多少订单
        LocalDateTime now = LocalDateTime.now();
        QueryWrapper<TbBizBsTime> bizBsTimeQueryWrapper = new QueryWrapper<TbBizBsTime>();
        bizBsTimeQueryWrapper.between("open_time", now.with(LocalTime.MIN), now.with(LocalTime.MAX));
        List<TbBizBsTime> tbBizBsTimeList = tbBizBsTimeService.list(bizBsTimeQueryWrapper);
        long bizTimeoutNum = 0L ;
        for (TbBizBsTime item : tbBizBsTimeList) {
            Long orderCallTime = item.getOrderCallTime();
            if (orderCallTime > 17 * 60) {
                bizTimeoutNum++;
            }
        }
        bizBiOrderDay.setBizTimeoutNum(new BigDecimal(bizTimeoutNum));
        bizBiOrderDay.setBizNum(new BigDecimal(tbBizBsTimeList.size()));
        // 总多少菜 超时多少菜， 今日菜品平均耗时：8分钟，
        QueryWrapper<TbKcKscTime> kcKscTimeQueryWrapper = new QueryWrapper<TbKcKscTime>();
        kcKscTimeQueryWrapper.between("call_up_time", now.with(LocalTime.MIN), now.with(LocalTime.MAX));
        kcKscTimeQueryWrapper.gt("order_call_time", 1);
        List<TbKcKscTime> tbKcKscTimeList = tbKcKscTimeService.list(kcKscTimeQueryWrapper);
        long kscTime = 0L;
        long kscTimeoutNum = 0L;
        long kscNum = 0L;
        long kscHisTime = 1000000L;
        for (TbKcKscTime item : tbKcKscTimeList) {
            if (NoTimeArchItemUtil.noTimeArchItem().contains(item.getItemId())) {
                continue;
            }
            Long orderCallTime = item.getOrderCallTime();
            kscTime = kscTime + orderCallTime;
            kscNum++;
            if (orderCallTime > 17 * 60) {
                kscTimeoutNum++;
            }
            if (orderCallTime.compareTo(kscHisTime) < 0) {
                kscHisTime = orderCallTime;
            }
        }
        bizBiOrderDay.setKscNum(new BigDecimal(kscNum));
        bizBiOrderDay.setKscTimeoutNum(new BigDecimal(kscTimeoutNum));
        if (kscNum != 0) {
            bizBiOrderDay.setKscTime(new BigDecimal(kscTime / kscNum).divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
        } else {
            bizBiOrderDay.setKscTime(BigDecimal.ZERO);
        }
        bizBiOrderDay.setKscHisTime(new BigDecimal(kscHisTime).divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
        bizBiOrderDayService.saveOrUpdate(bizBiOrderDay);
    }
}
